
/* 下来复选框
 * @Author: kevin.huang 
 * @Date: 2018-07-21 13:09:29 
 * @Last Modified by: kevin.huang
 * @Last Modified time: 2019-05-07 20:43:16
 * Copyright (c): kevin.huang Released under MIT License
 * 2019-05-17 修复input尚未加入dom中就调用创建时候，获取到高度、宽度为0的bug
 * 2019-08-19 新增disabled属性配置 禁用点击 下拉
 */
(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['$B', 'tree'], function (_$B) {
            return factory(global, _$B);
        });
    } else {
        if(!global["$B"]){
            global["$B"] = {};
        }
        factory(global, global["$B"]);
    }
}(typeof window !== "undefined" ? window : this, function (window, $B) {
    var $body;
    function _getBody(){
        if(!$body){
            $body = $(window.document.body).css("position", "relative");
        }
        return $body;        
    }
    var defaultOpts = {
        data: [], //数据 参考树数据
        default: {
            id: '',
            text: $B.config.comboxPlaceholder
        }, //默认选择项目
        mutilChecked: true, //是否多选
        checkfather: false, //是否可以选择父节点
        onlyNodeData: true, //是否仅节点数据（不包含children）
        tree2list: true,
        disabled:false, //不可操作
        initShow: false, //初始化时候是否显示下拉列表
        isTreeData: true, //是否是树形数据
        placeholder: $B.config.comboxPlaceholder,
        plainStyle: true, //true 为简单无图标样式
        extParamFiled: [], //异步加载时候，可以定义再传一个字段作为参数，默认不设置只传pid 
        search: undefined, //模糊搜索类型 remote/local  
        localSearchFiled: ['text'], //本地搜索的字段，默认只有一个text,可以设置多个字段
        url: '', //模糊查询自动完成时候的请求路径
        readonly: true, //不可以编辑
        textField: 'text', //菜单名称字段，默认为text
        idField: 'id', //菜单id字段,默认为id               
        onCheck: null, //点击事件 =function(data) data为当前选择的数据 ,可以不注册该事件，组件内部已经将数据赋值到input的 value 和 data-key属性中                 
        onClick: null //点击事件，点击后会自动收起，如果想点击后还不收起 请使用oncheck
    };

    function Combox(jqObj, opts) {
        $B.extend(this, Combox);        
        var _this = this;
        this.jqObj = jqObj.addClass("k_combox_input k_box_size").wrap("<div class='k_combox_input_wrap'></div>");
        setTimeout(function(){
            _this.jqObj.off("mouseover.textbox");
            _this.jqObj.off("mouseout.textbox");
            _this.jqObj.off("input.textbox");
        },500);
        this.jqObj.attr("autocomplete","off");
        this.iptWrap = this.jqObj.parent();
        if(opts.onCreateFn){
            opts.onCreateFn(this.iptWrap);
        }
        this.width = this.jqObj.outerWidth();
        this.height = this.jqObj.outerHeight();
        if(this.width === 0 || this.height === 0){
            var _ivt = setInterval(function(){
                _this.width = _this.jqObj.outerWidth();
                _this.height = _this.jqObj.outerHeight();
                if(_this.width !== 0 || _this.height !== 0){
                    clearInterval(_ivt);                   
                    _this.size.width = _this.width;
                    _this.size.height = _this.height - 1;
                    _this.icon.css("left","100%");
                    _this.dropList.children("ul").css("min-width",_this.width);
                    _this._fixLeftTop();
                }
            },200);
        }
        this.opts = $.extend({}, defaultOpts, opts);
        var chickFn = this.opts.onClick;        
        this.opts.onClick = function (datas, params) { //点击单选事件
            var nodeData = datas[0];
            var data = nodeData.data;
            if (!_this.opts.mutilChecked) {
                if (_this.opts.checkfather === false && params.isParent) { } else {
                    var id = nodeData[_this.opts.idField],
                        text = nodeData[_this.opts.textField];
                    if (typeof id === "undefined") {
                        id = data[_this.opts.idField];
                    }
                    if (!text) {
                        text = data[_this.opts.textField];
                    }
                    _this.jqObj.val(text).data("id", id);
                    if(typeof _this.onWatcher === "function"){//配合动态双向表单功能
                       _this.jqObj.data("no2update",true);
                    	_this.onWatcher.call(_this);
                    	setTimeout(function(){
                    		_this.jqObj.removeData("no2update");//不需要再更新这个el
                    	},1);
                    }
                    _this._fireValidFn();
                }
            }
            _this.hide(function () {
                if (typeof chickFn === 'function') {
                    setTimeout(function () {
                        try {
                            chickFn(data);
                        } catch (ex) {
                            _this.error("onClick is error " + ex.message);
                        }
                    }, 1);
                }
            });
        };
        this._onCheckFn = this.opts.onCheck;
        //var closedTimer;
        this.opts.onCheck = function (data, params, checked) {//多选事件
            _this._setInputValue(true);
            if (typeof _this._onCheckFn === "function") {
                setTimeout(function () {
                    _this._onCheckFn.call(_this, data, params, checked);
                }, 1);
            }
            if(typeof _this.onWatcher === "function"){//配合动态双向表单功能
                _this.onWatcher.call(_this);
            }            
        };
        this.opts.checkbox = this.opts.mutilChecked === true;
        this.size = {
            width: this.jqObj.outerWidth(),
            height: this.jqObj.outerHeight() - 1
        };
        if (!_this.opts.isTree) {
            this.opts.plain = true;
        }
        this.body = $(document.body).css('position', 'relative');
        var $win = $(window);
        var nsId = $B.getUUID();
        $win.on("resize."+nsId,function(){
            if(_this.repositon){
                _this.repositon();
            }else{
                $(this).off("."+nsId);
            }  
        });
        $win.on("click."+nsId,function(){
            if(_this.hide){
                _this.hide();
            }else{
                $(this).off("."+nsId);
            } 
        }); 
        var border_color = this.jqObj.css("border-color");
        this.dropList = $("<div class='k_box_size k_combox_wrap' style='z-index: 2147483647;position:abosulte;top:-100000px;min-width:" + this.size.width + "px;border-color:" + border_color + ";'><ul></ul></div>").appendTo(this.body).hide();
        this.dropList.data("direction", "d").data("combox", this);        
        this.jqObj.on({
            click: function () {
                if (_this.dropList.css("display") === 'none') {
                    _this.show();
                } else {
                    _this.hide();
                }
                return false;
            }
        });
        if(this.opts.disabled){
            this.jqObj.attr("disabled","disabled");
        }
        this.jqObj.attr("placeholder", this.opts.placeholder);
        this.jqObj.val(this.opts.default.text).data("id", this.opts.default.id);
        this._createTree();
        setTimeout(function () {
            _this.repositon();
        }, 1);        
        if (this.opts.readonly === true) {
            this.jqObj.attr("readonly", "readonly").css("cursor", "pointer");
        }
        this.icon = $("<div style='top:4px;left:100%;background:none;' class='k_tree_combox k_combox_input_icon btn'><i style='font-size:12px;margin-top:5px;position:relative;left:-16px;' class='fa fa-down-dir'></i></div>").appendTo(this.iptWrap);
        this.icon.click(function () {
            if(!_this.opts.disabled){
                _this.jqObj.trigger("click");
            }
            return false;
        });        
        var timer;
        this.initing = true;
        //开启输入模糊匹配localSearchFiled
        if (!this.opts.readonly && this.opts.search) {
            this.jqObj.on("input", function () {
                if (_this.tree && !_this.initing) {
                    var txt = $.trim(_this.jqObj.val().replace(/'/g, ''));
                    clearTimeout(timer);
                    if ($B.isUrl(_this.opts.url) && _this.opts.search === "remote") {
                        timer = setTimeout(function () {
                            _this.tree.reload(_this.dropList.children("ul"), {
                                keyword: txt
                            });
                        }, 500);
                    } else { //本地搜索
                        timer = setTimeout(function () {
                            _this._localSearch(txt);
                        }, 500);
                    }
                }
            });
        }
        this.jqObj.data("combox", this);        
        // var closedTimer ; 
        // this.dropList.on("mouseleave",function(){            
        //     closedTimer = setTimeout(function(){
        //         _this.hide();
        //     }, 1500);
        // }).on("mouseenter",function(){
        //     clearTimeout(closedTimer);            
        // });   
        this.jqObj.mouseenter(function(){
            var  $s = $(this);
            $s.attr("title",$s.val());
        });     
    }
    Combox.prototype = {
        constructor: Combox,
        _setInputValue: function (isImd) {
            var _this = this;    
            var data,id,text;        
            if(_this.opts.checkbox){
                var prs = {
                    onlyChild: !_this.opts.checkfather
                };
                data = _this.tree.getCheckedData(prs);                
                var setFn = function () {
                    var idArr = [],
                        txtArr = [];
                    for (var i = 0, l = data.length; i < l; ++i) {
                        var one = data[i];
                        id = one["id"];
                        text = one["text"];
                        if (!id && one.data) {
                            id = one.data[_this.opts.idField];
                        }
                        if (!text && one.data) {
                            text = one.data[_this.opts.textField];
                        }
                        idArr.push(id);
                        txtArr.push(text);
                    }
                    _this.jqObj.val(txtArr.join(",")).data("id", idArr.join(","));
                    _this._fireValidFn();
                };
                if(isImd){
                    setFn();
                }else{
                    clearTimeout( _this._setInputValueTimer);
                    _this._setInputValueTimer = setTimeout(setFn,100);
                }              
            }else{
                if(this.tree.clickedItem){
                    data = this.tree.clickedItem.data("data");
                    id = data["id"],                    
                    text = data["text"];
                    if(!id || !text){
                        if(data.data && !$.isEmptyObject(data.data)){
                            data = data.data;
                        }
                        if(!id){
                            id = data[_this.opts.idField];
                        }
                        if(!text){
                            text = data[_this.opts.textField];
                        }
                    }                    
                    _this.jqObj.val(text).data("id", id);
                }else{
                    this.jqObj.val(this.opts.default.text).data("id", this.opts.default.id);
                }
                _this._fireValidFn();
                //console.log("单选模式");
            }
        },
        /***触发验证***/
        _fireValidFn:function(){
            var _this = this;
            setTimeout(function(){
                _this.jqObj.trigger("mouseleave.kvalidate");
            },200);
        },
        _localSearch: function (txt) {
            if (this.dropList.css("display") === "none") {
                this.show();
            }
            this.tree.jqObj.children("._nodata_tip").remove();
            var i, len, c, p, wrap, ul, clickNode;
            var childs = this.tree.childNodesArray;
            var parents = this.tree.parentNodesArray;
            var deep = 0,
                tmpDeep, showParents;
            for (i = 0, len = parents.length; i < len; ++i) {
                p = parents[i].show();
                wrap = p.children("div");
                tmpDeep = parseInt(wrap.attr("deep"));
                if (tmpDeep > deep) {
                    deep = tmpDeep;
                }
                ul = p.children("ul");
                if (ul.css("display") === "none") {
                    clickNode = wrap.children("._line_node_");
                    if (clickNode.length === 0) {
                        clickNode = wrap.children("._node_");
                    }
                    clickNode.trigger("click");
                }
            }
            for (i = 0, len = childs.length; i < len; ++i) {
                c = childs[i];
                var data = c.children("div").data("data");
                if (this._isLike(data, txt)) {
                    c.show();
                } else {
                    c.hide();
                }
            }
            this._fixLeftTop();
            //修正父元素的显示
            deep++;
            while (deep > 0) {
                showParents = [];
                for (i = 0, len = parents.length; i < len; ++i) {
                    p = parents[i].show();
                    wrap = p.children("div");
                    ul = p.children("ul");
                    if (ul.height() === 0) {
                        p.hide();
                    } else {
                        showParents.push(p);
                    }
                }
                parents = showParents;
                deep--;
            }
            if (this.tree.jqObj.height() === 0) {
                var $li = $("<li class='_nodata_tip'>" + $B.config.noData + "</li>").appendTo(this.tree.jqObj);
                setTimeout(function () {
                    try {
                        $li.remove();
                    } catch (ex) { }
                }, 3000);
            }
        },
        _isLike: function (nodeData, txt) {
            if (txt === "") {
                return true;
            }
            var isLike = false;
            for (var i = 0, len = this.opts.localSearchFiled.length; i < len; i++) {
                var filed = this.opts.localSearchFiled[i];
                if (nodeData[filed] && nodeData[filed].indexOf(txt) >= 0) {
                    isLike = true;
                    break;
                }
                if (!isLike) {
                    if (nodeData.data[filed] && nodeData.data[filed].indexOf(txt) >= 0) {
                        isLike = true;
                        break;
                    }
                }
            }
            return isLike;
        },
        _createTree: function () {
            var _this = this;
            if (this.opts.data.length === 0 && this.opts.url !== "") {               
                this.jqObj.val("");
                this.jqObj.attr("placeholder", $B.config.loading);
                this.ajax({
                    url: this.opts.url,
                    ok: function (data, message) {
                        _this.opts.data = data;
                        _this._bindTree();
                    },
                    fail: function (message) { },
                    final: function (res) {
                        _this.jqObj.val(_this.opts.default.text).data("id", _this.opts.default.id);
                        _this.jqObj.attr("placeholder", $B.config.comboxPlaceholder);
                        if(_this.opts.onReqloaded){
                            _this.opts.onReqloaded(res);
                        }
                    }
                });
            } else {
                this._bindTree();
            }
        },
        _isFined:function(defId,datas){
            var go = true;
            for(var i = 0 ,len = datas.length ; i < len ; ++i){
                if(datas[i].id === defId){
                    go = false;
                    break;
                }
                if(datas[i].children){
                    go = this._isFined(defId,datas[i].children);
                    if(!go){
                        break;
                    }
                }
            }
            return go;
        },
        _bindTree: function () {
            if (!$.isEmptyObject(this.opts.default)) {
                if (!this.opts.default["data"]) {
                    this.opts.default["data"] = {};
                }
                if (this.opts.default.text !== '') {
                    /***树形递归检查数据项已经存在****/
                    var go = this._isFined(this.opts.default.id,this.opts.data);
                    if(go){
                        var defOtp = {};
                        defOtp[this.opts.idField] = this.opts.default.id;
                        defOtp[this.opts.textField] = this.opts.default.text;
                        defOtp.data = this.opts.default.data;
                        this.opts.data.unshift(defOtp);
                    }             
                }
            }
            var isLocalSearch = this.opts.search && this.opts.search === "local";
            this.opts.isLocalSearch = isLocalSearch;
            var _this = this;
            this.opts.onTreeCreated = function () {
                if( _this.initing){
                    _this._setInputValue(true);
                    if (_this.opts.initShow) {
                        _this.show();
                    } else {
                        _this.hide();
                    }
                }               
                _this.initing = false;
                if(_this.opts.onCreatedCall){
                    _this.opts.onCreatedCall();
                }
            };
            this.opts.onToggle = function () {
                _this._fixLeftTop();
            };
            this.opts.onloaded = function(){
                _this._setInputValue();
            };
            this.tree = new $B.Tree(this.dropList.children("ul"), this.opts);           
            if(!this.opts.mutilChecked){
                setTimeout(function(){
                    _this.tree.setClickedItem(_this.opts.default.id);
                },1000);               
            }           
        },
        repositon: function () {           
            var w = this.body.width(),
                h = this.body[0].scrollHeight;
            var offset = this.jqObj.offset(),
                maxWidth = w - offset.left,
                maxHeight = h - offset.top - this.height,
                topHeight = offset.top;
            var width = this.jqObj.parent().width()+"px";
            this.dropList.data("direction", "d");
            var top = offset.top + this.size.height;
            this.dropList.css({
                top: top,
                "overflow":'auto',
                left: offset.left,
                "min-width":width,
                "max-width": maxWidth,
                "max-height": maxHeight
            });
        },
        _fixLeftTop: function () {
            var offset = this.jqObj.offset();
            var top = offset.top + this.size.height;
            this.dropList.css({
                top: top,
                left: offset.left
            });
        },
        reset: function () {
            this._setBreakHide();
            this.jqObj.val(this.opts.default.text).data("id", this.opts.default.id);
            this.tree.reset();
        },
        _setBreakHide: function () {
            var _this = this;
            this._breakHide = true;
            setTimeout(function () {
                _this._breakHide = false;
            }, 300);
        },
        getCheckedData: function () {
            this._setBreakHide();
            if(!this.tree){
                return [];
            }
            if (this.opts.mutilChecked) {
                return this.tree.getCheckedData();
            } else {
                return this.tree.getClickItem();
            }
        },
        getCheckedIds: function () {
            this._setBreakHide();
            if(!this.tree){
                return [];
            }
            if (this.opts.mutilChecked) {
                return this.tree.getCheckedData({
                    onlyId: true
                });
            } else {
                return this.jqObj.data("id");
            }
        },
        hide: function (fn) {
            if (this._breakHide) {
                return;
            }
            if (this.dropList.data("direction") === "d") {
                this.dropList.slideUp(200, function () {
                    if (typeof fn === 'function') {
                        fn();
                    }
                    var _t = this;
                    _getBody().children(".k_combox_wrap").each(function () {
                        if (_t !== this) {
                            $(this).data("combox")._fixLeftTop();
                        }
                    });
                });
            } else {
                this.dropList.hide();
                if (typeof fn === 'function') {
                    fn();
                }
            }
            if (this.icon) {
                this.icon.children().addClass("fa-down-dir").removeClass("fa-up-dir").css("margin-top", "5px");
            }
        },
        show: function () {
            var _this = this;
            this.repositon();           
            if (this.dropList.data("direction") === "d") {
                this.dropList.slideDown(200, function () {
                    _this._fixLeftTop();
                    var _t = this;
                    _getBody().children(".k_combox_wrap").each(function () {
                        if (_t !== this) {
                            $(this).data("combox")._fixLeftTop();
                        }
                    });
                });
            } else {
                this.dropList.css({
                    "display": "block",
                    "top": 0
                });
            }
            if (this.icon) {
                this.icon.children().removeClass("fa-down-dir").addClass("fa-up-dir").css("margin-top", "5px");
            }
        },
        val:function(){
           return this.jqObj.data("id");
        },
        /**
         * 设置勾选/选择的数据，适配mvvm联动
         * datas = []; datas = "id1,id2,id3"
         * ***/
        setCheckDatas:function(datas){ 
            if(this.tree){
                var _this = this;
                if(this.tree.running > 0){
                    setTimeout(function(){
                        _this.setCheckDatas(datas);
                    },150); 
                    return;               
                }
                if(this.opts.mutilChecked){
                    this.tree.setCheckDatas(datas);          
                }else{
                    this.tree.setClickedItem(datas);
                }
                this._setInputValue(true);
                if(typeof this.onWatcher === "function"){//配合动态双向表单功能
                    this.onWatcher.call(this);
                }
            }           
        },
        /**重写destroy**/
        destroy: function () {
            this.dropList.remove();
            this["super"].destroy.call(this);
        }
    };
    $B["Combox"] = Combox;
    return Combox;
}));